#pragma once
#include<iostream>
#include<fcntl.h>
#include<string>
#include <fstream>
#include <sys/stat.h>
#include<sys/time.h>
#include <mutex>

#include"../CommonComponent/Log.hpp"

namespace ns_common
{
    static int id;          //一个编号，用于生成唯一文件名
    static mutex _mutex;    //互斥锁保证id增长时的安全性

    class fileUtility
    {
    public:
        fileUtility()
        {}

        ~fileUtility()
        {}

        static std::string AddSuffix(std::string name,std::string suffix){
            return name+suffix;
        }

        static std::string AddSrcSuffix(std::string& name){
            return AddSuffix(name,".cpp");
        }

        static std::string AddCompileErrSuffix(std::string& name){
            return AddSuffix(name,".cstderr");
        }

        static std::string AddRunErrSuffix(std::string& name){
            return AddSuffix(name,".rstderr");
        }

        static std::string AddOutSuffix(std::string& name){
            return AddSuffix(name,".stdout");
        }

        static std::string AddInSuffix(std::string& name){
            return AddSuffix(name,".stdin");
        }

        static std::string AddExeSuffix(std::string& name){
            return AddSuffix(name,".exe");
        }

        static bool IsFileEsist(std::string& filepath){
            struct stat st;
            if (stat(filepath.c_str(), &st) == 0)
            {
                //获取属性成功，文件已经存在
                return true;
            }

            return false;
        }

        static std::string GetUniqueFileName(){
            struct timeval _time;
            gettimeofday(&_time, nullptr);
            std::string filename=std::to_string(_time.tv_sec )+ std::to_string(_time.tv_usec / 1000);
            _mutex.lock();
            id=(id+1)%(INT32_MAX-1);
            filename+=std::to_string(id);
            _mutex.unlock();

            return filename;
        }

        static bool IsFileEmpty(std::string filepath){
            struct stat st;
            if (stat(filepath.c_str(), &st) != 0)
            {
                //文件不存在，当作空
                return true;
            }

            if(0==st.st_size){
                return true;
            }
            return false;
        }

        static bool Read(std::string filepath,std::string& content,bool iskeep=true){
            std::ifstream in(filepath);
            if(!in.is_open()){
                return false;
            }
            std::string tmp;
            while(std::getline(in,tmp))
            {
                content+=tmp;
                if(iskeep){
                    content+="\n";
                }
            }
            in.close();

            return true;
        }

        static bool CreateFile(std::string filepath,int privileges=0664){
            int fd = open(filepath.c_str(), O_WRONLY | O_CREAT | O_TRUNC, privileges);
            if (fd == -1) {
                return false;
            }
            close(fd);

            return true;
        }

        static bool Write(std::string filepath,std::string& content){
            std::ofstream out(filepath);
            if(!out.is_open()){
                return false;
            }
            
            out.write(content.c_str(),content.size());
            out.close();

            return true;
        }
    };
}